package GUI;

import java.util.ArrayList;

import Control.Shape;
import Control.Shape.Category;
import Control.Shape.Shapes;

public class Graph {
	int x,y,width,height;
	String xAxisString0,xAxisString1,yAxisString0,yAxisString1;//,yAxisString2;
	int maxYValue;
	ArrayList<String> xLabels;
	int minX,maxX;



	public Graph(int x,int y,int width,int height,int maxYValue,
			String xAxisString0,String xAxisString1,String yAxisString0,String yAxisString1, int minX,int maxX){
		this.x=x;
		this.y=y;
		this.width=width;
		this.height=height;
		this.maxYValue = maxYValue;
		xLabels = new ArrayList<String>();
		this.xAxisString0 = xAxisString0;
		this.xAxisString1 = xAxisString1;
		this.yAxisString0 = yAxisString0;
		this.yAxisString1 = yAxisString1;
		this.minX = minX;
		this.maxX = maxX;
		GV.graphPoints = new ArrayList<ArrayList<Integrator>>();
	}

	public void draw(){

		drawAxisLabels();
		drawYLabels();
		drawXLabels();
		drawGraphPoints();

		drawHighLight();
	}

	private void drawHighLight() {
		int numOfzero=0;

		for(int j=0;j<GV.colors.length;j++){
			if(GV.shapesSelected.size()>=j+1){
				for(int i=0;i<GV.graphPoints.size();i++){
					if(!GV.shapeCategoryColor){if(GV.graphPoints.get(0).get(j).target == 0) break;}
					//float yVal= GV.graphPoints.get(i).get(j).value;
					float xVal= GV.graphPoints.get(i).get(j).xValue;
					float yTarget = GV.graphPoints.get(i).get(j).target;
					float YSumTarget=0;
					for(int k=0;k<GV.colors.length;k++){
						YSumTarget += GV.graphPoints.get(i).get(k).target;
					}
					float YSumVal=0;
					for(int k=0;k<=j;k++){
						YSumVal += GV.graphPoints.get(i).get(k).value;
					}
					int xV = (int) GV.processing.map(xVal, minX,maxX,x,x+width);
					int yV = (int) GV.processing.map(YSumVal, 0, maxYValue, y+height, y); 

					if(Math.abs(GV.processing.mouseX-xV)<7 && Math.abs(GV.processing.mouseY-yV)<5){
						GV.processing.fill(GV.backGroundColor); 
						GV.processing.rectMode(GV.processing.CORNER); 
						GV.processing.noStroke();
						String shapeName = Shapes.values()[((GV.graphPoints.get(i).get(j).shapeNum))].name().toLowerCase();
						String categoryName = Category.values()[j].name().toLowerCase();
						if(xV>GV.processing.width/2){
							if(GV.shapeCategoryColor){
								xV= (int) (xV -40 - GV.processing.textWidth(("Num of sightings of shape "+shapeName+": "+(int)(yTarget))));
								GV.processing.rect(xV+10, yV, GV.processing.textWidth(("Num of sightings of shape "+shapeName+": "+(int)(yTarget)))+15,40);
							}
							else{
								xV= (int) (xV -40 - GV.processing.textWidth(("Num of sightings of category "+categoryName+": "+(int)(yTarget))));
								GV.processing.rect(xV+10, yV, GV.processing.textWidth(("Num of sightings of category "+categoryName+": "+(int)(yTarget)))+15,40);
							}
						}
						else if(GV.shapeCategoryColor){
							GV.processing.rect(xV+10, yV, GV.processing.textWidth(("Num of sightings of shape "+shapeName+": "+(int)(yTarget)))+15,40);

						}else{
							GV.processing.rect(xV+10, yV, GV.processing.textWidth(("Num of sightings of category "+categoryName+": "+(int)(yTarget)))+15,40);

						}
						GV.processing.fill(GV.textColor);
						GV.processing.textAlign(GV.processing.LEFT);
						GV.processing.text("Total number of sightings: "+(int)(YSumTarget),xV+12,yV+13);
						if(GV.shapeCategoryColor){
							GV.processing.text("Num of sightings of shape "+shapeName+": "+(int)(yTarget),xV+12, yV+28);
						}
						else{
							GV.processing.text("Num of sightings of category "+categoryName+": "+(int)(yTarget),xV+12, yV+28);

						}
					}
				}
			}
		}
	}

	public void drawGraphPoints(){
		if(GV.graphPoints.size()==0)return; if(GV.graphPoints.get(0).size()==0)return;
		boolean updated=false; 
		for (int j=0;j< GV.graphPoints.size();j++) {
			for(int i=0;i<GV.colors.length;i++){
				try {
					if (GV.graphPoints.get(j).get(i).update()) {
						updated=true;
					}
				}
				catch(NullPointerException e) {/*println("integratore null");*/}
			}
		}
		GV.processing.beginShape();
		GV.processing.stroke(140);
		GV.processing.fill(GV.colors[0]);
		for (int j=0;j< GV.graphPoints.size();j++) {
			float yVal= GV.graphPoints.get(j).get(0).value;
			float xVal= GV.graphPoints.get(j).get(0).xValue;
			int xV = (int) GV.processing.map(xVal, minX,maxX,x,x+width);
			int yV = (int) GV.processing.map(yVal, 0, maxYValue, y+height, y); 
			GV.processing.vertex(xV, yV);
		}
		GV.processing.vertex(x+width, y+height);
		GV.processing.vertex(x,y+height);
		GV.processing.endShape(GV.processing.CLOSE);
		for(int i=1;i<GV.colors.length;i++){
			if(GV.shapesSelected.size()>=i+1){
				GV.processing.beginShape();
				GV.processing.stroke(140);
				GV.processing.fill(GV.colors[i]);
				for (int j=GV.graphPoints.size()-1;j>=0;j--) {
					float yVal=0;
					float xVal= GV.graphPoints.get(j).get(i).xValue;
					for(int k=0;k<=i;k++){
						yVal = yVal + GV.graphPoints.get(j).get(k).value;
					}
					int xV = (int) GV.processing.map(xVal, minX,maxX,x,x+width);
					int yV = (int) GV.processing.map(yVal, 0, maxYValue, y+height, y); 
					GV.processing.vertex(xV, yV);
				}
				for (int j=0;j< GV.graphPoints.size();j++) {
					float yVal=0;
					float xVal= GV.graphPoints.get(j).get(i-1).xValue;
					for(int k=0;k<=i-1;k++){
						yVal = yVal + GV.graphPoints.get(j).get(k).value;
					}
					int xV = (int) GV.processing.map(xVal, minX,maxX,x,x+width);
					int yV = (int) GV.processing.map(yVal, 0, maxYValue, y+height, y); 
					GV.processing.vertex(xV, yV);
				}
				GV.processing.endShape(GV.processing.CLOSE);
			}else break;
		}
	}



	public void drawAxisLabels(){
		GV.processing.fill(GV.textColor);
		GV.processing.textSize(11);
		GV.processing.textLeading(15);
		int labelX= x -65;
		int labelY= y +height+ 20;

		GV.processing.textAlign( GV.processing.CENTER,  GV.processing.CENTER);
		GV.processing.text(yAxisString0, labelX, y+(height)/2-40);

		GV.processing.text(yAxisString1, labelX, y+(height)/2-11);
		//GV.processing.text(yAxisString2, labelX, y+(height)/2+9);
		GV.processing.textAlign( GV.processing.CENTER);
		GV.processing.text(xAxisString0+" "+xAxisString1, x+(width)/2, labelY+25);
		//GV.processing.text(xAxisString1, x+(width)/2, labelY+20);


	}

	public void drawYLabels(){
		int offset = maxYValue/10;
		int i;
		GV.processing.stroke(60); 
		for(i=0;i<=maxYValue/offset;i++){
			float yVal = GV.processing.map((float) (i),0,maxYValue/offset,y+height,y);
			GV.processing.line(x,yVal,x+width,yVal);
			GV.processing.text(i*offset,x-13,yVal+5);
		}

	}



	public void drawXLabels(){
		int startValue = 0;
		GV.processing.stroke(60); 
		int max = xLabels.size();
		float interval = (float)max/20;
		if(interval<1) interval =1;
		interval = (int)(interval+0.5);
		int offset=12,i;
		GV.processing.textAlign( GV.processing.CENTER,  GV.processing.CENTER);
		for(i=startValue;i<max;i+=interval){
			float xVal;
			if(startValue +max-1!=0)
				xVal = GV.processing.map((float) (i),startValue,startValue+max-1,x,x+width);
			else xVal= x;
			//if(i!=startValue && i+1<startValue+max)
			GV.processing.line(xVal,y,xVal,y+height);
			GV.processing.text(xLabels.get(i), xVal, y+8+offset+height);
			if(offset==0)
				offset=12;
			else offset=0;
		}
		if(i-interval!=max-1){
			float xVal2 = GV.processing.map((float) (max-1),startValue,startValue+max-1,x,x+width);
			GV.processing.text(xLabels.get(max-1), xVal2, y+8+offset);

		}


	}


}
